/**
 * @file      FlexGraphInterface.h
 *
 * @brief     The functions from this header file are
 *            exported by FlexGraph.dll.
 *
 * @author    Michael Purwins
 *
 * @copyright This file has no specific license attached. Use it in any way you like.
 *            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *            OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *            IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 *            DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 *            TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 *            SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#pragma once

//! Error definitions
enum _FG_ERROR
{
    FG_ERROR_NULLPOINTER_PARAMETER = -1000,
    FG_ERROR_INVALID_CONTROL_HANDLE,
    FG_ERROR_INVALID_GRAPH_HANDLE,
    FG_ERROR_BORDER_SIZE_CAPPED
};

#define FG_EXPORT extern __declspec(dllexport)

#ifdef BUILD_FG  // Used when building FlexGraph

#include "stdafx.h"
#include <map>
#include "_GraphDialog.h"
#include <memory>
using namespace std::tr1;
static map<_FGHandle, shared_ptr<_GraphDialog>> OpenGraphs;
static int CreatedGraphs = 0;

#else           // Used for dll interface

typedef int          _FGHandle;
typedef int          _s32;
typedef unsigned int _u32;
typedef double       _f64;

/**
* @brief   Windows type for RGB colors (Hex: 0x00bbggrr),
* @details See Windef.h http://msdn.microsoft.com/en-us/library/windows/desktop/dd183449(v=vs.85).aspx
*/
typedef COLORREF     DWORD;

/**
*  @brief Structure for Points in 2d space
*/
class _2DPoint {
    public:
        _f64 X; //! X-coordinate
        _f64 Y; //! Y-coordinate
};

#endif

/**
* @brief  Creates a new graph control window
*
* @detail The window is created as an overlay, using the given coordinates.
*         The control size behaves a little different in different GUI-libraries,
*         Just try to play around with the WindowLeft, WindowTop coordinates if
*         you run into trouble.
*
* @param  hWnd        - Window handle of the destination window or control (parent).
* @param  Left        - X-coordinate of the left side of the new graph control
* @param  Top         - Y-coordinate of the top side of the new graph control
* @param  Width       - Width of the new graph control in pixels
* @param  Height      - Height of the new graph control in pixels
* @param  WindowLeft  - X-coordinate of the left side of the parent application window, usually not needed
* @param  WindowTop   - Y-coordinate of the top side of the parent application window, usually not needed
*
* @return Positive handle to the new graph control if successful.
*         Negative values are error codes.
*/
FG_EXPORT _FGHandle FG_createGraphControl(void* hWnd,
                                          _s32 Left,
                                          _s32 Top,
                                          _s32 Width,
                                          _s32 Height,
                                          _s32 WindowLeft = 0,
                                          _s32 WindowTop = 0
                                         );

/**
* @brief  Removes the graph control given a handle
*
* @param  ControlHandle - Handle of the graph control to delete
*
* @return 0 if successful
*         1 if not
*/
FG_EXPORT _s32 FG_removeGraphControl(_FGHandle ControlHandle);

/**
* @brief  Adds a new graph to a control
*
* @param  ControlHandle - Handle of the graph control to delete
* @param  Title         - Title of the new graph
*
* @return Positive handle to the new graph if successful.
*         Negative values are error codes.
*/
FG_EXPORT _FGHandle FG_addGraph(_FGHandle ControlHandle, wchar_t* Title = L"");

/**
* @brief  Adds a new graph to a control
*
* @param  ControlHandle - Handle of the graph control to delete
*
* @return Positive handle to the new graph if successful.
*         Negative values are error codes.
*/
FG_EXPORT _FGHandle FG_addGraphEx(_FGHandle ControlHandle);

/**
* @brief  Removes a graph from a control
*
* @param  ControlHandle - Handle of the graph control
* @param  GraphHandle   - Handle of the graph to remove
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_removeGraph(_FGHandle ControlHandle, _FGHandle GraphHandle);

/**
* @brief  Removes all graph from a control
*
* @param  ControlHandle - Handle of the graph control
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_removeAllGraphs(_FGHandle ControlHandle);

/**
* @brief  Sets the visibility of a graphcontrol
*
* @param  ControlHandle - Handle of the graph control
* @param  Visible       - New visibility value
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_setVisible(_FGHandle ControlHandle, bool Visible);

/**
* @brief  Gets the visibility of a graphcontrol and saves it to pVisible
*
* @param  ControlHandle - Handle of the graph control
* @param  pVisible      - Pointer to which the output is saved
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getVisible(_FGHandle ControlHandle, bool* pVisible);

/**
* @brief  Adds a new point to a graph
*
* @param  ControlHandle - Handle of the graph control
* @param  GraphHandle   - Handle of the specific graph inside the control
* @param  x             - X-value of the new point
* @param  y             - Y-value of the new point
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_addPoint(_FGHandle ControlHandle, _FGHandle GraphHandle, _f64 x, _f64 y);

/**
* @brief  Forces a graph control to redraw
*
* @param  ControlHandle - Handle of the graph control
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_requestRedraw(_FGHandle ControlHandle);

/**
* @brief  Sets new min/max values for the axes
*
* @param  ControlHandle - Handle of the graph control
* @param  X_Min         - New minimum value of the x-axis
* @param  X_Max         - New maximum value of the x-axis
* @param  Y_Min         - New minimum value of the y-axis
* @param  Y_Max         - New maximum value of the y-axis
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_setMinMax(_FGHandle ControlHandle,
                            _f64 X_Min,
                            _f64 X_Max,
                            _f64 Y_Min,
                            _f64 Y_Max
                           );

/**
* @brief  Gets the current min/max values for the axes
*
* @param  ControlHandle - Handle of the graph control
* @param  X_Min         - Pointer where current minimum value of the x-axis is saved to
* @param  X_Max         - Pointer where current maximum value of the x-axis is saved to
* @param  Y_Min         - Pointer where current minimum value of the y-axis is saved to
* @param  Y_Max         - Pointer where current maximum value of the y-axis is saved to
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getMinMax(_FGHandle ControlHandle,
                            _f64* X_Min,
                            _f64* X_Max,
                            _f64* Y_Min,
                            _f64* Y_Max
                           );

/**
* @brief  Sets the axis ranges to the min/max values +/- 10%.
*         So that all points on the graph are visible.
*
* @param  ControlHandle - Handle of the graph control
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_setDefaultZoom(_FGHandle ControlHandle);

/**
* @brief  Returns the number of graphs in a specified graph control
*
* @param  ControlHandle - Handle of the graph control
*
* @return Number of graphs in the specified control
*/
FG_EXPORT _s32 FG_getNumOfGraphs(_FGHandle ControlHandle);

/**
* @brief  Sets the border color of a specified control
*
* @param  ControlHandle - Handle of the graph control
* @param  Color         - New border color
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_setBorderColor(_FGHandle ControlHandle, COLORREF Color);


/**
* @brief  Gets the border color of a specified control
*
* @param  ControlHandle - Handle of the graph control
* @param  pColor        - Pointer where the border color is saved to
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getBorderColor(_FGHandle ControlHandle, COLORREF* pColor);

/**
* @brief  Sets the border size of a specified control
*
* @param  ControlHandle - Handle of the graph control
* @param  Size          - New border size
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_setBorderSize(_FGHandle ControlHandle, _u32 Size);

/**
* @brief  Saves the current border size to pSize
*
* @param  ControlHandle - Handle of the graph control
* @param  pSize         - Pointer to output value
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getBorderSize(_FGHandle ControlHandle, _u32* pSize);

/**
* @brief  Sets a new line color for a graph
*
* @param  ControlHandle - Handle of the graph control
* @param  GraphHandle   - Handle of a specific graph
* @param  Color         - New line color
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_setLineColor(_FGHandle ControlHandle,
                               _FGHandle GraphHandle,
                               COLORREF Color
                              );

/**
* @brief  Saves current line color to location specified by pColor
*
* @param  ControlHandle - Handle of the graph control
* @param  GraphHandle   - Handle of a specific graph
* @param  pColor        - Pointer to output value
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getLineColor(_FGHandle ControlHandle,
                               _FGHandle GraphHandle,
                               COLORREF* pColor
                              );

/**
* @brief  Sets a new point color for a graph
*
* @param  ControlHandle - Handle of the graph control
* @param  GraphHandle   - Handle of a specific graph
* @param  Color         - New point color
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_setPointColor(_FGHandle ControlHandle,
                                _FGHandle GraphHandle,
                                COLORREF Color
                               );

/**
* @brief  Saves current point color to location specified by pColor
*
* @param  ControlHandle - Handle of the graph control
* @param  GraphHandle   - Handle of a specific graph
* @param  pColor        - Pointer to output value
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getPointColor(_FGHandle ControlHandle,
                                _FGHandle GraphHandle,
                                COLORREF* pColor
                               );

/**
* @brief  Sets a new visibility for a graph
*
* @param  ControlHandle - Handle of the graph control
* @param  GraphHandle   - Handle of a specific graph
* @param  Visible       - New visibility
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_setGraphVisible(_FGHandle ControlHandle,
                                  _FGHandle GraphHandle,
                                  bool Visible
                                 );

/**
* @brief  Saves the current visibility of a graph to pVisible
*
* @param  ControlHandle - Handle of the graph control
* @param  GraphHandle   - Handle of a specific graph
* @param  pVisible      - Pointer to output location
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getGraphVisible(_FGHandle ControlHandle,
                                  _FGHandle GraphHandle,
                                  bool* pVisible
                                 );

/**
* @brief  Adds a new marker on the x-axis
*
* @param  ControlHandle - Handle of the graph control
* @param  Value         - Value at which the marker is set
* @param  Label         - Label for the marker
* @param  Color         - Color of the marker
*
* @return Positive handle for the new marker
*         If the function fails, a negative errorcode
*/
FG_EXPORT _FGHandle FG_addXMarker(_FGHandle ControlHandle,
                                  _f64 Value,
                                  wchar_t* Label,
                                  COLORREF Color
                                 );

/**
* @brief  Adds a new marker on the y-axis
*
* @param  ControlHandle - Handle of the graph control
* @param  Value         - Value at which the marker is set
* @param  Label         - Label for the marker
* @param  Color         - Color of the marker
*
* @return Positive handle for the new marker
*         If the function fails, a negative errorcode
*/
FG_EXPORT _FGHandle FG_addYMarker(_FGHandle ControlHandle,
                                  _f64 Value,
                                  wchar_t* Label,
                                  COLORREF Color
                                 );

/**
* @brief  Removes a marker given a marker handle
*
* @param  ControlHandle - Handle of the graph control
* @param  MarkerHandle  - Handle of the marker to remove
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_removeMarker(_FGHandle ControlHandle, _FGHandle MarkerHandle);

/**
* @brief  Gets the title as unicode string
*
* @param  ControlHandle - Handle of the graph control
* @param  pReturnBuffer - Buffer for the output string
* @param  BufferSize    - Size of the output buffer in bytes
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getTitleAsUnicode(_FGHandle ControlHandle,
                                    wchar_t* pReturnBuffer,
                                    _u32 BufferSize
                                   );

/**
* @brief  Gets the title as ascii (single byte) string
*
* @param  ControlHandle - Handle of the graph control
* @param  pReturnBuffer - Buffer for the output string
* @param  BufferSize    - Size of the output buffer in bytes
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getTitleAsAscii(_FGHandle ControlHandle,
                                  char* pReturnBuffer,
                                  _u32 BufferSize
                                 );

/**
* @brief  Sets the title of a graph control
*
* @param  ControlHandle - Handle of the graph control
* @param  Title         - New title
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_setTitle(_FGHandle ControlHandle, wchar_t* Title);

/**
* @brief  Gets the label of the x-axis as unicode string
*
* @param  ControlHandle - Handle of the graph control
* @param  pReturnBuffer - Buffer for the output string
* @param  BufferSize    - Size of the output buffer in bytes
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getAxisLabelXAsUnicode(_FGHandle ControlHandle,
                                         wchar_t* pReturnBuffer,
                                         _u32 BufferSize
                                        );


/**
* @brief  Gets the label of the x-axis as ascii string (single byte)
*
* @param  ControlHandle - Handle of the graph control
* @param  pReturnBuffer - Buffer for the output string
* @param  BufferSize    - Size of the output buffer in bytes
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getAxisLabelXAsAscii(_FGHandle ControlHandle,
                                       char* pReturnBuffer,
                                       _u32 BufferSize
                                      );

/**
* @brief  Sets the label of the x-axis of a graph control
*
* @param  ControlHandle - Handle of the graph control
* @param  Label         - New label
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_setAxisLabelX(_FGHandle ControlHandle, wchar_t* Label);

/**
* @brief  Gets the label of the y-axis as unicode string
*
* @param  ControlHandle - Handle of the graph control
* @param  pReturnBuffer - Buffer for the output string
* @param  BufferSize    - Size of the output buffer in bytes
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getAxisLabelYAsUnicode(_FGHandle ControlHandle,
                                         wchar_t* pReturnBuffer,
                                         _u32 BufferSize
                                        );

/**
* @brief  Gets the label of the y-axis as ascii string (single byte)
*
* @param  ControlHandle - Handle of the graph control
* @param  pReturnBuffer - Buffer for the output string
* @param  BufferSize    - Size of the output buffer in bytes
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getAxisLabelYAsAscii(_FGHandle ControlHandle,
                                       char* pReturnBuffer,
                                       _u32 BufferSize
                                      );

/**
* @brief  Sets the label of the y-axis of a graph control
*
* @param  ControlHandle - Handle of the graph control
* @param  Label         - New label
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_setAxisLabelY(_FGHandle ControlHandle, wchar_t* Label);

/**
* @brief  Enables or disables the grid for a specified graph control
*
* @param  ControlHandle - Handle of the graph control
* @param  Enable        - Visibility of the grid (true == enabled)
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_setEnableGrid(_FGHandle ControlHandle, bool Enable);

/**
* @brief  Saves the current status of the grid to an output pointer
*
* @param  ControlHandle - Handle of the graph control
* @param  pEnable       - Output location for visibility of the grid
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT _s32 FG_getGridEnabled(_FGHandle ControlHandle, bool* pEnable);

/**
* @brief  Enables or disables fullscreen view
*
* @detail NOT IMPLEMENTED YET!!!
* @todo   Implement
*
* @param  ControlHandle - Handle of the graph control
* @param  Enable        - Enable == true, disable == false
*
* @return 0 if successful
*         Errorcode if not
*/
FG_EXPORT void FG_setFullscreen(_FGHandle ControlHandle, bool Enable);

/**
* @brief  Enables or disables fullscreen view
*
* @param  ControlHandle - Handle of the graph control
* @param  GraphHandle   - Handle of a graph
*
* @return Positive number of points if successful
*         Negative errorcode if not
*/
FG_EXPORT _u32 FG_getNumberOfPoints(_FGHandle ControlHandle, _FGHandle GraphHandle);

/**
* @brief  Returns a pointer to the point array
*
* @detail Use the FG_getNumberOfPoints() function to get the array length
*
* @param  ControlHandle - Handle of the graph control
* @param  GraphHandle   - Handle of a graph
*
* @return Positive number of points if successful
*         Null if not successfull
*/
FG_EXPORT _2DPoint* FG_getPoints(_FGHandle ControlHandle, _FGHandle GraphHandle);

/**
* @brief  Retrieves x-axis marker handle from index.
*
* @detail Use this function in a loop to get all markers on the x-axis.
*         It will return a positive handle unless you reached the end of the marker list.
*
* @param  ControlHandle - Handle of the graph control
* @param  Index         - Index for marker list, starting at 0
*
* @return Positive marker handle if marker is available at that index.
*         -1 if that index is not in marker list anymore.
*         Errorcode if there was a problem.
*/
FG_EXPORT _FGHandle FG_getMarkerHandleX(_FGHandle ControlHandle, _u32 Index);

/**
* @brief  Retrieves y-axis marker handle from index.
*
* @detail Use this function in a loop to get all markers on the y-axis.
*         It will return a positive handle unless you reached the end of the marker list.
*
* @param  ControlHandle - Handle of the graph control
* @param  Index         - Index for marker list, starting at 0
*
* @return Positive marker handle if marker is available at that index.
*         -1 if that index is not in marker list anymore.
*         Errorcode if there was a problem.
*/
FG_EXPORT _FGHandle FG_getMarkerHandleY(_FGHandle ControlHandle, _u32 Index);

/**
* @brief  Retrieves marker value given a specific marker handle.
*
* @param  ControlHandle - Handle of the graph control
* @param  Markerhandle  - Handle of a marker
* @param  pValue        - Pointer to _f64 to save the value
*
* @return 0 if everything went alright.
*         -1 if the specified marker was not found.
*         Negative errorcode if there was a problem.
*/
FG_EXPORT _s32 FG_getMarkerValue(_FGHandle ControlHandle,
                                 _FGHandle Markerhandle,
                                 _f64*     pValue);

/**
* @brief  Retrieves marker caption given a marker handle
*
* @param  ControlHandle - Handle of the graph control
* @param  Markerhandle  - Handle of a marker
* @param  pBuffer       - Buffer for the output string
* @param  Size          - Buffer size in byte
*
* @return Number of characters in Buffer if the request was successful.
*         -1 if the specified marker was not found.
*         Negative errorcode if there was a problem.
*/FG_EXPORT _s32 FG_getMarkerCaption_AsUnicode(_FGHandle ControlHandle,
                                               _FGHandle Markerhandle,
                                               wchar_t*  pBuffer,
                                               _u32      Size);

/**
* @brief  Retrieves marker caption given a marker handle
*
* @param  ControlHandle - Handle of the graph control
* @param  Markerhandle  - Handle of a marker
* @param  pBuffer       - Buffer for the output string
* @param  Size          - Buffer size in byte
*
* @return Number of characters in Buffer if the request was successful.
*         -1 if the specified marker was not found.
*         Negative errorcode if there was a problem.
*/
FG_EXPORT _s32 FG_getMarkerCaption_AsAscii(_FGHandle ControlHandle,
                                           _FGHandle Markerhandle,
                                           char*     pBuffer,
                                           _u32      Size);